package game.ball;

import game.ball.Free;
import game.players.SoccerPlayer;
import game.scene.MatchScene;
import game.soccerField.Arc;
import game.soccerField.SoccerField;

import com.uqbar.vainilla.DeltaState;
import com.uqbar.vainilla.GameComponent;
import com.uqbar.vainilla.appearances.Animation;
import com.uqbar.vainilla.appearances.Sprite;

public class SoccerBall extends GameComponent<MatchScene> {

	private double ratio = 22.5;
	private SoccerBallState state;
	private SoccerPlayer lastTouched;
	private boolean goalLinePassed = false;
	
	public SoccerBall(int x, int y) {
		super(x,y);
		this.setState(new Free(this));
	}
	
	public void setRightAnimationWithSpeed(double meanTime) {
		this.setAppearance(new Animation(meanTime,
				Sprite.fromImage("/images/ball.png").crop(2, 193, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(65, 130, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(2, 130, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(65, 65, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(2, 65, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(65, 2, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(2, 2, 60, 60).scale(0.75)
				));
	}
	
	public void setLeftAnimationWithSpeed(double meanTime) {
		this.setAppearance(new Animation(meanTime,
				Sprite.fromImage("/images/ball.png").crop(2, 2, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(65, 2, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(2, 65, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(65, 65, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(2, 130, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(65, 130, 60, 60).scale(0.75),
				Sprite.fromImage("/images/ball.png").crop(2, 193, 60, 60).scale(0.75)
				));
	}
	
	@Override
	public void update(DeltaState deltaState) {
		super.update(deltaState);
		Arc arc1 = this.getScene().getLeftArc();
		Arc arc2 = this.getScene().getRightArc();
		
		if (this.goThroughTheLeftGoal(arc1) && !this.getScene().isAnnouncing() && !this.isGoalLinePassed())
			this.validateGoal(arc1);
		
		if (this.goThroughTheRightGoal(arc2) && !this.getScene().isAnnouncing() && !this.isGoalLinePassed())
			this.validateGoal(arc2);
		
		this.getState().update(deltaState);
	}

	private void validateGoal(Arc arc) {
		this.setGoalLinePassed(true);
		this.getScene().updateScoreboard(arc);
		this.getScene().showPlayersAttitudeAfterGoal(arc);
		this.getScene().announceGoal(arc);
		
		if (this.collidesWithNet())
			this.setState(new Free(this));
	}


	private boolean collidesWithNet() {
		Arc arc1 = this.getScene().getLeftArc();
		Arc arc2 = this.getScene().getRightArc();
		return this.getX() <= arc2.getX() || this.getX() + this.getAppearance().getWidth() >= arc1.getX() + arc1.getAppearance().getWidth();
	}
	
	private boolean goThroughTheRightGoal(Arc arc) {
		return this.getX() > arc.getX() && this.getY() > arc.getY() + 90 && this.getY() < arc.getY() + arc.getAppearance().getHeight();
	}
	
	private boolean goThroughTheLeftGoal(Arc arc) {
		return this.getX() < arc.getX() + arc.getAppearance().getWidth() -50 && this.getY() > arc.getY() + 90
				&& this.getY() < arc.getY() + arc.getAppearance().getHeight() - 5;
	}

	public void moveNormally(double x, double y) {
		SoccerField field = this.getScene().getField();	
		this.getState().move(field, x, y);
	}
	
	public void locateBall(double x, double y) {
		this.getScene().locateBall(x, y);
	}
	
	public void roll(int speed, double i, double j) {
		this.setState(new Free(this, speed, i, j));		
	}
	
	public boolean isWithinField() {
		return this.getState().isWithinTheField(this.getScene().getField());
	}
	
	public boolean isFree(){
		return this.state.isFree();
	}
	
	
	

	public double getRatio() {
		return ratio;
	}

	public SoccerBallState getState() {
		return state;
	}

	public void setState(SoccerBallState state) {
		this.state = state;
	}
	
	public SoccerPlayer getPlayer(){
		if(this.isFree())
			return null;
		else
			return ((Possessed)this.getState()).getPlayer();
	}

	public SoccerPlayer getLastTouched() {
		return lastTouched;
	}

	public void setLastTouched(SoccerPlayer lastTouched) {
		this.lastTouched = lastTouched;
	}

	public boolean isGoalLinePassed() {
		return goalLinePassed;
	}

	public void setGoalLinePassed(boolean goalLinePassed) {
		this.goalLinePassed = goalLinePassed;
	}
	
	
}
